package com.yl.util;

import cn.hutool.core.collection.ListUtil;
import cn.hutool.core.date.DateUtil;
import cn.hutool.core.util.StrUtil;
import cn.hutool.json.JSONObject;
import cn.hutool.json.JSONUtil;
import com.hawkeye.entity.EmailVO;
import com.hawkeye.util.SMSUtil;
import com.tencentcloudapi.common.Credential;
import com.tencentcloudapi.vms.v20200902.VmsClient;
import com.tencentcloudapi.vms.v20200902.models.SendTtsVoiceRequest;
import com.tencentcloudapi.vms.v20200902.models.SendTtsVoiceResponse;
import com.yl.constant.Const;
import com.yl.constant.Warn;
import com.yl.entity.MultiDataEntity;
import com.yl.entity.PrimaryWarn;
import com.yl.entity.cdc.*;
import lombok.extern.slf4j.Slf4j;
import okhttp3.*;
import org.eclipse.paho.client.mqttv3.MqttClient;
import org.eclipse.paho.client.mqttv3.MqttException;
import org.eclipse.paho.client.mqttv3.MqttMessage;
import org.eclipse.paho.client.mqttv3.MqttTopic;

import java.io.File;
import java.io.IOException;
import java.util.List;

/**
 * @author wlf
 * @since 2022/8/22
 */
@Slf4j
public class SendUtil {

    /**
     * mqtt 推送信息
     *
     * @param mqttClient  MqttClient
     * @param topic       发送的主题
     * @param primaryWarn 告警信息
     */
    public static void sendMqtt(MqttClient mqttClient, String topic, PrimaryWarn primaryWarn) {
        MqttMessage mqttMessage = new MqttMessage();
        mqttMessage.setQos(1);
        mqttMessage.setRetained(false);
        mqttMessage.setPayload(JSONUtil.toJsonStr(primaryWarn).getBytes());
        MqttTopic mqttTopic = mqttClient.getTopic(topic);
        try {
            mqttTopic.publish(mqttMessage);
//            log.info("告警信息mqtt推送成功！");
        } catch (MqttException e) {
            log.error("告警信息mqtt推送失败！", e);
            e.printStackTrace();
        }
    }

    /**
     * ding 推送信息
     *
     * @param httpClient  OkHttpClient
     * @param signUrl     加签地址
     * @param title       消息头信息，通常为项目名称
     * @param primaryWarn 告警信息
     */
    public static void sendDing(OkHttpClient httpClient, String signUrl, String title, PrimaryWarn primaryWarn) {
        JSONObject jsonObject = new JSONObject();
        //固定参数
        jsonObject.set("msgtype", "text");
        JSONObject content = new JSONObject();
        //此处message是你想要发送到钉钉的信息
        content.set("content", title + "\r" + primaryWarn.msg());
        jsonObject.set("text", content);
        RequestBody body = RequestBody.create(
                MediaType.parse("application/json; charset=utf-8"), jsonObject.toString());
        Request request = new Request.Builder().url(signUrl).post(body).build();
        try (Response response = httpClient.newCall(request).execute()) {
            ResponseBody responseBody = response.body();
            if (responseBody != null) {
                log.info("告警信息ding推送成功！{}", responseBody.string());
            }
        } catch (IOException e) {
            log.error("告警信息ding推送失败！", e);
            e.printStackTrace();
        }
    }

    /**
     * email 推送信息
     *
     * @param projectKey  项目key，通常为项目编号
     * @param email       发送邮件地址
     * @param attachFiles 附加文件
     * @param primaryWarn 告警信息
     */
    public static void sendEmail(String projectKey, String email, List<File> attachFiles, PrimaryWarn primaryWarn) {
        try {
            String project = primaryWarn.getMultiDataEntity().getProject().getName();
            String titleTpl = "{}项目{}预警";
            EmailVO emailVO = EmailVO.builder()
                    .email(email)
                    .title(StrUtil.format(titleTpl, project, primaryWarn.getWarn().getName()))
                    .content(JSONUtil.toJsonStr(primaryWarn))
                    .build();
            SMSUtil.sendMail(projectKey, emailVO, attachFiles);
            log.info("告警信息邮件推送成功！{},{},{}", email, attachFiles, primaryWarn.msg());
        } catch (Exception e) {
            log.error("告警信息邮件推送失败！", e);
            e.printStackTrace();
        }
    }

    /**
     * email 推送信息
     *
     * @param projectKey  项目key，通常为项目编号
     * @param email       发送邮件地址
     * @param primaryWarn 告警信息
     */
    public static void sendEmail(String projectKey, String email, PrimaryWarn primaryWarn) {
        try {
            String project = primaryWarn.getMultiDataEntity().getProject().getName();
            List<File> files = ListUtil.toList();
            String titleTpl = "{}项目{}预警";
            EmailVO emailVO = EmailVO.builder()
                    .email(email)
                    .title(StrUtil.format(titleTpl, project, primaryWarn.getWarn().getName()))
                    .content(primaryWarn.msg())
                    .build();
            SMSUtil.sendMail(projectKey, emailVO, files);
            log.info("告警信息邮件推送成功！{},{}", email, primaryWarn.msg());
        } catch (Exception e) {
            log.error("告警信息邮件推送失败！", e);
            e.printStackTrace();
        }
    }

    // 测试邮件发送程序
//    public static void main(String[] args) {
//        String projectKey = "cr11g_landslip";
//        String email = "waisaa@qq.com";
//        PrimaryWarn primaryWarn = PrimaryWarn.builder()
//                .multiDataEntity(MultiDataEntity.builder()
//                        .project(BaseProject.builder().name("测试项目").build())
//                        .target(BaseTarget.builder().code("ceshi").build())
//                        .targetType(BaseTargetType.builder().name("测试类型").build())
//                        .build())
//                .warn(Warn.RED)
//                .quota(SettingsDataQuota.builder().name("测试指标").build())
//                .warnTime(DateUtil.date())
//                .dataValue(8.1)
//                .th(SettingsThreshold.builder().lower(8.0).upper(10.0).build())
//                .build();
//        sendEmail(projectKey, email, primaryWarn);
//    }

    /**
     * 短信 推送信息
     *
     * @param projectKey  项目key，通常为项目编号
     * @param phone       发送手机号
     * @param primaryWarn 告警信息
     */
    public static void sendMsg(String projectKey, String phone, PrimaryWarn primaryWarn) {
        try {
            SMSUtil.sendMsg(projectKey, phone, primaryWarn.msg());
            log.info("告警信息短信推送成功！{},{}", phone, primaryWarn.msg());
            log.info("【提示】如果未收到短信，请确认是否录入了项目key:{}!", projectKey);
        } catch (Exception e) {
            log.error("告警信息短信推送失败！", e);
            e.printStackTrace();
        }
    }


    /**
     * 语音 推送信息
     * ·语音消息模板·
     * 【尊敬的用户您好，{1}项目中测点{2}的{3}产生了{4}预警，测点类型{5}，阈值范围为{6}到{7}，请登录系统及时处理！】
     * 例如：尊敬的用户您好，{天全车站1#滑坡体}项目中测点{BC01}的{水平位移}产生了{一级}预警，测点类型为{北斗}，
     * 阈值范围为{20毫米}到{999999毫米}，请登录系统及时处理！
     * <p>
     * 【templateParamSet】
     * [项目名称，测点编号，指标名称，告警等级，测点类型，阈值下限带单位，阈值上限带单位]
     * [天全车站1#滑坡体，BC01，水平位移，一级，北斗，20毫米，999999毫米]
     *
     * @param phone       发送手机号
     * @param primaryWarn 告警信息
     */
    public static void sendVoice(String phone, PrimaryWarn primaryWarn) {
        try {
            String templateId = "1153782";
            String project = primaryWarn.getMultiDataEntity().getProject().getName();
            String targetCode = primaryWarn.getMultiDataEntity().getTarget().getCode();
            String quota = primaryWarn.getQuota().getName();
            String warn = primaryWarn.getWarn().getName();
            String type = primaryWarn.getMultiDataEntity().getTargetType().getName();
            String lowerTh = primaryWarn.getTh().getLower().toString();
            String upperTh = primaryWarn.getTh().getUpper().toString();
            String[] templateParamSet = {project, targetCode, quota, warn, type, lowerTh, upperTh};
            if (TimerUtil.voiceTimer(phone)) {
                log.info("phone:{},templateParamSet:{}", phone, templateParamSet);
                /* 腾讯云账户密钥对等信息 */
                String region = "ap-beijing";
                String voiceSdkAppId = "1400573016";
                String secretId = "AKIDEEyShfMmwpRmqd9OM4KK3VhcGcjaATWI";
                String secretKey = "wf7JEtHOEn57sMZVAZhY9TWIo31i8NL2";
                // 被叫手机号码， 格式为+[电话区号][用户号码]
                String calledNumber = Const.TEL_RC + phone;

                Credential cred = new Credential(secretId, secretKey);
                VmsClient client = new VmsClient(cred, region);
                SendTtsVoiceRequest req = new SendTtsVoiceRequest();
                req.setTemplateId(templateId);
                req.setTemplateParamSet(templateParamSet);
                req.setCalledNumber(calledNumber);
                req.setVoiceSdkAppid(voiceSdkAppId);
                SendTtsVoiceResponse res = client.SendTtsVoice(req);
                log.info("告警信息语音推送成功！{},{},{}", SendTtsVoiceResponse.toJsonString(res), phone, templateParamSet);
                TimerUtil.setVoiceTimer(phone);
            }
        } catch (Exception e) {
            log.error("告警信息语音推送失败！", e);
            e.printStackTrace();
        }
    }

}
